package com.zb.nio.asyncfilechannel;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.Future;

import org.junit.Test;

/**
 * @author: zhaobin
 * @date: 2024/2/25 11:10
 * @Description:
 */
public class AsyncFileChannelDemo {

    @Test
    public void testReadAsyncFileChannel() throws IOException {
        // 1、得到文件路径
        Path path = Paths.get("./src/main/resources/03.txt");

        // 2、创建AsynchronousFileChannel
        AsynchronousFileChannel afc = null;
        try {
            afc = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 3、创建缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);

        // 4、把通道中的数据读到缓冲区，得到Future
        Future<Integer> future = afc.read(buf, 0);

        // 5、判断是否读取完成
        while (!future.isDone()) {
        }

        // 6、输出
        buf.flip();
        System.out.println(new String(buf.array(), 0, buf.limit()));
        buf.clear();

        // 7、关闭
        afc.close();
    }


    @Test
    public void testCompletionHandlerRead() {
        // 1、得到文件路径
        Path path = Paths.get("./src/main/resources/03.txt");
        // 2、创建AsynchronousFileChannel
        AsynchronousFileChannel afc = null;
        try {
            afc = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 3、创建缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);
        // 4、把通道中的数据读到缓冲区
        afc.read(buf, 0, buf, new CompletionHandler<Integer, ByteBuffer>() {
            /**
             * 读取完成
             * @param result
             * @param attachment
             */
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                System.out.println("读取到：" + result);

                attachment.flip();
                System.out.println(new String(attachment.array(),0,attachment.limit()));
                attachment.clear();
            }

            /**
             * 读取失败
             * @param exc
             * @param attachment
             */
            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                System.out.println("读取失败！");
            }
        });
    }

    @Test
    public void testWriteAsyncFileFuture() throws IOException {
        // 1、得到文件路径
        Path path = Paths.get("./src/main/resources/04.txt");
        // 2、创建AsynchronousFileChannel
        AsynchronousFileChannel afc = null;
        try {
            afc = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 3、创建缓冲区
        //        ByteBuffer buf = ByteBuffer.allocate(1024);
        //        buf.put("测试abc".getBytes());
        //        buf.flip();
        ByteBuffer buf = ByteBuffer.wrap("测试testWriteAsyncFileFuture".getBytes());

        // 4、把缓冲区中的数据写入通道，得到Future
        Future<Integer> future = afc.write(buf, 0);

        // 5、判断是否写入完成
        while (!future.isDone()) {
        }

        // 6、输出
        System.out.println("写入完成！");

        // 7、关闭
        afc.close();
    }

    @Test
    public void testWriteAsyncFileCompletion() {
        // 1、得到文件路径
        Path path = Paths.get("./src/main/resources/04.txt");
        // 2、创建AsynchronousFileChannel
        AsynchronousFileChannel afc = null;
        try {
            afc = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 3、创建缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);
        buf.put("测试testWriteAsyncFileCompletion".getBytes());
        buf.flip();
        // 4、把缓冲区中的数据写入通道
        afc.write(buf, 0, null, new CompletionHandler<Integer, ByteBuffer>() {
            /**
             * 写入完成
             * @param result
             * @param attachment
             */
            @Override
            public void completed(Integer result, ByteBuffer attachment) {
                System.out.println("写入：" + result);
            }

            /**
             * 写入失败
             * @param exc
             * @param attachment
             */
            @Override
            public void failed(Throwable exc, ByteBuffer attachment) {
                System.out.println("写入失败！");
            }
        });
    }




}
